#!/usr/bin/env python

# encoding: utf-8

'''
 * Create File crawler
 * Created by leixu on 2017/10/16
 * IDE PyCharm
'''
from luobocrawler.params import RedisParamGetter

from ..holder.driver_config import custom_chrome_config
from ..holder.holders import CustomerSessionHolder
import traceback


class Crawler(object):
    def __init__(self):
        self.driver_type = None
        self.config = None
        self._session_holder = None
        self.driver_config = None
        self.ref_config = {}
        self.params_getter = None
        self.param_deliver = None

    def init_env(self):
        pass

    def gen_param_getter(self, param_deliver):
        self.params_getter = RedisParamGetter()
        self.params_getter.load_config(param_deliver)

    def build_crawler(self, param_deliver):
        """

        :param param_deliver: param deliver config
        :return:
        """
        # 初始化任务传递
        self.param_deliver = param_deliver
        self.gen_param_getter(param_deliver)
        # 初始化参数
        self.init_env()
        self.build_session()

    def build_session(self):
        if self._session_holder is None:
            self._session_holder = CustomerSessionHolder()
        if self.driver_type is None:
            self.driver_type = "chrome"

        # 开启driver
        self._start_session(self.driver_type, self.driver_config, self.ref_config)

    def rebuild(self):
        self.driver.quit()
        self.build_session()

    def _start_session(self, driver_type="chrome", driver_config=None, ref_config={}):
        """

        :param driver_config:
        :param ref_config: use custome config,ref_config
            example: {"folder": "facebook_folder"}  it means specify the folder to put chrome user-data
            example: {"is_headless": True}  it means set chrome headless mode
        :return:
        """
        self.driver_type = driver_type
        if driver_config is None:
            self.config = custom_chrome_config(**ref_config)
        else:
            self.config = driver_config
        self._session_holder.chose_driver_type(type=self.driver_type, config=self.config)
        self.driver = self._session_holder.start_session()

    def _close_session(self):
        self._session_holder.close_driver()

    async def async_crawl_rule(self, rule_index, *args, **kwargs):
        try:
            if hasattr(self, f"rule_{rule_index}"):
                return await getattr(self, f"rule_{rule_index}")(*args, **kwargs)
            else:
                raise Exception(f"No such rule_index {rule_index} found in your object")
        except Exception as e:
            return traceback.format_exc()
        finally:
            self._close_session()

    def crawl_rule(self, rule_index, *args, **kwargs):
        try:
            if hasattr(self, f"rule_{rule_index}"):
                return getattr(self, f"rule_{rule_index}")(*args, **kwargs)
            else:
                raise Exception(f"No such rule_index {rule_index} found in your object")
        except Exception as e:
            return traceback.format_exc()
        finally:
            self._close_session()
